import React from 'react';
import moment from 'moment';
import { Icon } from 'antd-mobile';
import styles from './index.less';

const WEEK = ['日', '一', '二', '三', '四', '五', '六'];
const WEEK_NUM = WEEK.length;

// new Date()第三个参数为0时,返回上个月最后一天
const getMonthDay = (year, month) => new Date(year, month + 1, 0).getDate();

const defaultValue = moment();

const Calendar = React.memo(({ dates, day, handleClick, expandRow, expand }) => (
    <table className={styles.calendarTable}>
        <tbody>
            <tr>
                {WEEK.map(item => (
                    <th key={item}>{item}</th>
                ))}
            </tr>
            {dates.map((date, index) => {
                const columnNum = WEEK_NUM;
                const rowIndex = Math.floor(index / columnNum);
                const isRow = index % columnNum === 0;
                if (isRow) {
                    const extraRowClass = !expand && rowIndex !== expandRow ? styles.hideTr : null;
                    return (
                        <tr key={rowIndex} className={extraRowClass}>
                            {[...Array(columnNum).keys()].map(columnIndex => {
                                const cellDate = dates[rowIndex * columnNum + columnIndex];
                                const extraClass = [];
                                if (columnIndex === 0 || columnIndex === 6) extraClass.push(styles.grayColor);
                                if (day === cellDate) extraClass.push(styles.selected);
                                return (
                                    <td
                                        key={`${rowIndex}_${columnIndex}`}
                                        onClick={() => {
                                            handleClick(cellDate, rowIndex);
                                        }}
                                        className={extraClass.join(' ')}
                                    >
                                        <span>{cellDate}</span>
                                    </td>
                                );
                            })}
                        </tr>
                    );
                }
                return null;
            })}
        </tbody>
    </table>
));

export default React.forwardRef(({ value = defaultValue, onChange, onExpandChange, extra = null }, ref) => {
    const [expand, setExpand] = React.useState(true);
    const [expandRow, setExpandRow] = React.useState(0);
    const year = value.year();
    const month = value.month();
    const day = value.date();
    // const weekday = value.weekday();
    const maxDay = getMonthDay(year, month);
    const firstWeekday = moment(value)
        .startOf('month')
        .weekday(); // 需要一个新的实例

    // 未到本月的日期填充空值
    const dates = [
        ...Array(firstWeekday !== 6 ? firstWeekday + 1 : 0), // 考虑第一行为空的情况
        ...[...Array(maxDay).keys()].map(item => item + 1)
    ];

    const handleClick = React.useCallback(
        nextDay => {
            if (!nextDay) return;
            const nextDate = moment()
                .year(year)
                .month(month)
                .date(nextDay);

            onChange(nextDate);
        },
        [month, year]
    );

    const handleMonthChange = React.useCallback(
        val => {
            const nextDate = moment(value.add(val, 'month').startOf('month')); // 需要一个新的实例

            onChange(nextDate);
        },
        [month, value]
    );

    const handleExpand = () => {
        onExpandChange(!expand);
        setExpand(!expand);
    };

    const calenderProps = {
        dates,
        day,
        handleClick,
        expandRow,
        expand
    };

    React.useEffect(() => {
        const dateIndex = dates.findIndex(item => item === day);
        setExpandRow(Math.floor(dateIndex / WEEK_NUM));
    }, [day, dates]);

    const apiHandler = () => ({
        getExpand: () => expand
    });

    React.useImperativeHandle(ref, apiHandler);

    return (
        <div>
            <div className={styles.headBar}>
                <div className={styles.barLeft}>
                    <Icon
                        type="left"
                        onClick={() => {
                            handleMonthChange(-1);
                        }}
                    />
                    <div className={styles.yearMonth}>{value.format('YYYY-MM')}</div>
                    <Icon
                        type="right"
                        onClick={() => {
                            handleMonthChange(1);
                        }}
                    />
                </div>
                <div className={styles.barRight}>{extra}</div>
            </div>
            <div className={styles.calendarWrap}>
                <Calendar {...calenderProps} />
            </div>
            <div className={styles.btmBar}>
                <Icon type={expand ? 'up' : 'down'} onClick={handleExpand} />
            </div>
        </div>
    );
});
